/*
    Copyright (C) 1998-2004  Charles MacDonald

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/

#include "shared.h"

bitmap_t bitmap;
cart_t cart;                
input_t input;

static int iline_table[] = {0xC0, 0xE0, 0xF0};

/* Run the virtual console emulation for one frame */
void system_frame(int skip_render)
{
  int lpf = sms.display ? 313 : 262;
  int iline;

  /* Debounce pause key */
  if(input.system & INPUT_PAUSE)
  {
    if(!sms.paused)
    {
      sms.paused = 1;
      z80_set_irq_line(INPUT_LINE_NMI, ASSERT_LINE);
      z80_set_irq_line(INPUT_LINE_NMI, CLEAR_LINE);
    }
  }
  else
  {
     sms.paused = 0;
  }

  /* reset TMS Text offset counter */
  text_counter = 0;

  /* End of frame, parse sprites for line 0 on line 261 (VCount=$FF) */
  if(vdp.mode <= 7) parse_line(0);

  /* 3D glasses faking */
	if (sms.glasses_3d) skip_render = (sms.wram[0x1ffb] == 0) ? 1 : 0;

	for(vdp.line = 0; vdp.line < lpf;)
  {
    z80_execute(CYCLES_PER_LINE);

    iline = iline_table[vdp.extended];

    if(!skip_render)
    {
      render_line(vdp.line);
    }

    if(vdp.line <= iline)
    {
      vdp.left -= 1;
      if(vdp.left == -1)
      {
        vdp.left = vdp.reg[0x0A];
        vdp.hint_pending = 1;

        z80_execute(16);

        if(vdp.reg[0x00] & 0x10)
        {
          z80_set_irq_line(0, ASSERT_LINE);
        }
      }
    }
    else
    {
      vdp.left = vdp.reg[0x0A];
    }

    if(vdp.line == iline)
    {
      vdp.status |= 0x80;
      vdp.vint_pending = 1;

      z80_execute(16);

      if(vdp.reg[0x01] & 0x20)
      {
        z80_set_irq_line(0, ASSERT_LINE);
      }
    }

    sound_update(vdp.line);

    ++vdp.line;

    if(vdp.mode <= 7) parse_line(vdp.line);
  }
}

void system_init(void)
{
  error_init();
  sms_init();
  pio_init();
  vdp_init();
  render_init();
  sound_init();
}

void system_shutdown(void)
{
  sms_shutdown();
  pio_shutdown();
  vdp_shutdown();
  render_shutdown();
  sound_shutdown();
  error_shutdown();
}

void system_reset(void)
{
  sms_reset();
  pio_reset();
  vdp_reset();
  render_reset();
  sound_reset();
  system_manage_sram(cart.sram, SLOT_CART, SRAM_LOAD);
}

void system_manage_sram(uint8 *sram, int slot, int mode)
{
}

void system_poweron(void)
{
  system_init();
	system_reset();
}

void system_poweroff(void)
{
  system_manage_sram(cart.sram, SLOT_CART, SRAM_SAVE);
}
